home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / snip0493.zip / FRACTION.C < prev    next >
C/C++ Source or Header  |  1993-04-05  |  2KB  |  81 lines

  1. /*
  2. **  FRACTION.C - Convert a floating point value to an integer ratio
  3. **
  4. **  public domain by Bob Stout
  5. */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <math.h>
  10.  
  11. unsigned char n, d;
  12.  
  13. double real2ratio(double Realnum)
  14. {
  15.       int i, Trial, Seed = 255;
  16.       double Residue, Minres = 255.;
  17.  
  18.       if (1. == Realnum || 0. == Realnum)
  19.       {
  20.             n = (unsigned char) Realnum;
  21.             d = (unsigned char) 1;
  22.             return Realnum;
  23.       }
  24.       if (1.0 < Realnum)
  25.       {
  26.             Seed = (int)(255./Realnum);
  27.             if (255 % (int)Realnum)
  28.                   ++Seed;
  29.       }
  30.       for (i = Seed; i; --i)
  31.       {
  32.             Trial = (int)((Realnum * (double)i) + 0.5);
  33.             if (255 < Trial)
  34.                   continue;
  35.             Residue = Realnum - ((double)Trial/(double)i);
  36.             if (0. > Residue)
  37.                   Residue = 0. - Residue;
  38.             if (Residue < Minres)
  39.             {
  40.                   d = (unsigned char) i;
  41.                   n = (unsigned char) Trial;
  42.                   Minres = Residue;
  43.             }
  44.       }
  45.       return ((double)n / (double)d);
  46. }
  47.  
  48. void blow_off(void)
  49. {
  50.       puts("\aUsage:   FRACTION decimal_fraction");
  51.       puts("returns: decimal_fraction = integer / integer");
  52. }
  53.  
  54. void range_error(double err_num, char *string)
  55. {
  56.       blow_off();
  57.       printf("\ndecimal_fraction must be %G or %s.\n", err_num, string);
  58.       exit(EXIT_FAILURE);
  59. }
  60.  
  61. int main(int argc, char *argv[])
  62. {
  63.       double Fraction, result;
  64.  
  65.       if (argc < 2)
  66.       {
  67.             blow_off();
  68.             return EXIT_FAILURE;
  69.       }
  70.       Fraction = atof(argv[1]);
  71.       if (255. < Fraction)
  72.             range_error((255.), "less");
  73.       if ((1./255.) > Fraction && Fraction != 0.)
  74.             range_error((1./255.), "greater");
  75.       result = real2ratio(Fraction);
  76.       printf("\nClosest integer fraction approximating %G is:\n", Fraction);
  77.       printf("%d / %d (%Xh / %Xh) = %G", n, d, n, d, result);
  78.       printf(" (Error = %6.3G%%)\n", 100. * (Fraction - result) / Fraction);
  79.       return EXIT_SUCCESS;
  80. }
  81.